package net.kelissa.divizor;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import net.kelissa.divizor.model.CellModel;
import net.kelissa.divizor.model.DivizorModel;
import net.kelissa.divizor.model.StatDivizor;
import net.kelissa.divizor.util.Const;
import net.kelissa.divizor.util.MathUtil;

public class Divizor implements Callable<Double>
{
  private List<StatDivizor> stats;
  private DivizorModel model;
  private int steps;

  @Override
  public Double call()
  {
    DivizorModel piece;
    for (int i = 0; i < steps; i++)
    {
      System.out.println("---------------| " + i + " |----------");
      System.out.println("fittness : " + i + " " + MathUtil.calcStat(model).getFitness());
      int cellId = selectCell(this.model);
      int deep = selectDeep(this.model, cellId);
      System.out.println("-cellId " + cellId + "   deep " + deep);
      piece = this.model.cut(cellId, deep);
      piece = trainDivizor(piece);
      this.model.paste(piece);
    }
    return 0d;
  }




  private DivizorModel trainDivizor(DivizorModel divizorPiece)
  {
//    TrainerComponent trainer = new TrainerComposite(divizorPiece, Const.TRAIN_TREE_DEEP, Const.TRAIN_LENGTH);
//    trainer.setDivizor(divizorPiece);
//    for (int i = 0; i < Const.TRAIN_STEPS; i++)
//    {
////      System.out.println("ciclo: " + i + " " + MathUtil.calcStat(trainer.getDivizor()).getFitness());
//      trainer.train();
//    }
//    return trainer.getDivizor();
  //TODO
  return null;
  }





  public int selectDeep(DivizorModel dataModel, int cellId)
  {
    return MathUtil.getRandom().nextInt(Const.CUT_MAX_DEEP + 1);
  }





  public int selectCell(DivizorModel dataModel)
  {
    Map<Integer, CellModel> cells = dataModel.getCells();
    int size = cells.size();
    int rand = MathUtil.getRandom().nextInt(size);
    Integer[] v = new Integer[size];
    return cells.keySet().toArray(v)[rand];
  }





  //  ---- GETTERS AND SETTERS --------
  public List<StatDivizor> getStats()
  {
    return stats;
  }
  public void setStats(List<StatDivizor> stats)
  {
    this.stats = stats;
  }

  public DivizorModel getModel()
  {
    return model;
  }
  public void setModel(DivizorModel model)
  {
    this.model = model;
  }

  public int getSteps()
  {
    return steps;
  }
  public void setSteps(int steps)
  {
    this.steps = steps;
  }
}
